package com.ttx.single.lab.service.defaultimpl;

import com.ttx.single.lab.mapper.OrderItemMapper;
import com.ttx.single.lab.mapper.OrderMapper;
import com.ttx.single.lab.model.bo.OrderBO;
import com.ttx.single.lab.model.bo.OrderItemBO;
import com.ttx.single.lab.model.dataobject.OrderDO;
import com.ttx.single.lab.model.dataobject.OrderItemDO;
import com.ttx.single.lab.model.dto.PlaceOrderDto;
import com.ttx.single.lab.model.dto.PlaceOrderItemDto;
import com.ttx.single.lab.service.OrderService;
import com.ttx.suite.web.model.bo.PageBO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;

/**
 * @author
 * @date
 */
@Service("defaultOrderService")
public class OrderServiceImpl implements OrderService {

    //注入单库数据源的mapper
    @Autowired
    @Qualifier("singleOrderMapper")
    protected OrderMapper orderMapper;
    @Autowired
    @Qualifier("singleOrderItemMapper")
    protected OrderItemMapper orderItemMapper;

    @Deprecated //分库分表使用了唯一id生成器生成自定义id， sql需要修改，原来的已不适用
    @Transactional
    @Override
    public void placeOrder(PlaceOrderDto orderDto) {
        OrderDO orderDO=new OrderDO();
        Date date=new Date();
        BeanUtils.copyProperties(orderDto,orderDO);
        orderDO.setCreateTime(date);
        orderDO.setUpdateTime(date);

        orderMapper.insert(orderDO);


        List<PlaceOrderItemDto> itemDtos=orderDto.getItemDtos();
        Assert.state(!CollectionUtils.isEmpty(itemDtos), "订单项个数必须大于0");

        OrderItemDO itemDO=null;

        for(PlaceOrderItemDto placeOrderItemDto: itemDtos){//为方便示例，所以循环插入
            itemDO=new OrderItemDO();
            BeanUtils.copyProperties(placeOrderItemDto, itemDO);
            itemDO.setOrderId(orderDO.getOrderId());
            itemDO.setCreateTime(date);
            itemDO.setUpdateTime(date);

            orderItemMapper.insert(itemDO);
        }

    }

    @Override
    public PageBO<OrderBO> listUserOrderPage(Long userId, Integer pageNum, Integer pageSize) {

        Assert.notNull(userId,"[userId]不能为空");
        Assert.notNull(pageNum, "[pageNum]不能为空");
        Assert.notNull(pageSize, "[pageSize]不能为空");
        Assert.state(pageNum>0, "[pageNum]需 大于0");
        Assert.state(pageSize>0 && pageSize<200, "[pageSize]需 大于0 且 小于200");


        Integer pageIndex=(pageNum-1) * pageSize;
        List<OrderDO> orderDOS=orderMapper.listUserOrderPage(userId,pageIndex,pageSize);
        Long count=orderMapper.countUserOrder(userId);

        PageBO<OrderBO> pageBO=new PageBO<>();
        pageBO.setTotal(count);
        pageBO.setPages(count/pageSize);

        if(CollectionUtils.isEmpty(orderDOS)){
            pageBO.setData(new ArrayList<>());
            return pageBO;
        }


        List<Long> orderIds=orderDOS.stream().map(order-> order.getOrderId()).collect(Collectors.toList());
        List<OrderItemDO> itemDOS=orderItemMapper.listUserOrderItem(userId, orderIds);
        Map<Long, List<OrderItemDO>> itemDoMap=itemDOS.stream()
                .collect(groupingBy(OrderItemDO::getOrderId)); //根据orderId分组

        //组装结果
        OrderBO orderBO=null;
        List<OrderBO> orderBOS=new ArrayList<>();
        List<OrderItemBO> orderItemBOS=null;
        List<OrderItemDO> orderItemDOS=null;
        for(OrderDO orderDO: orderDOS){
            orderBO=new OrderBO();
            orderBOS.add(orderBO);
            BeanUtils.copyProperties(orderDO,orderBO);

            orderItemDOS=itemDoMap.get(orderDO.getOrderId());
            if(CollectionUtils.isEmpty(orderDOS)){
                orderItemBOS=new ArrayList<>();
            }else{
                orderItemBOS=orderItemDOS.stream().map(itemDo->{
                    OrderItemBO itemBO=new OrderItemBO();
                    BeanUtils.copyProperties(itemDo, itemBO);
                    return itemBO;
                }).collect(Collectors.toList());
            }
            orderBO.setOrderItemBOList(orderItemBOS);
        }

        pageBO.setData(orderBOS);
        return pageBO;
    }

    @Override
    public OrderBO selectOrder(Long orderId) {

        OrderDO orderDO=orderMapper.selectByOrderId(orderId);
        if(orderDO==null){
            return null;
        }
        List<OrderItemDO> itemDOS=orderItemMapper.listOrderItemByOrderId(orderId);


        OrderBO orderBO=new OrderBO();
        BeanUtils.copyProperties(orderDO,orderBO);

        List<OrderItemBO> itemBOS=itemDOS.stream().map(itemDO->{
            OrderItemBO itemBO=new OrderItemBO();
            BeanUtils.copyProperties(itemDO, itemBO);
            return itemBO;
        }).collect(Collectors.toList());

        orderBO.setOrderItemBOList(itemBOS);

        return orderBO;
    }

    @Override
    public void cancelOrder(Long orderId, Integer userId) {
        Assert.notNull(userId,"[userId]不能为空");
        Assert.notNull(orderId,"[orderId]不能为空");


        orderMapper.updateOrderStatus(orderId, userId, "cancel", new Date());
    }
}
